home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 2.0
-
- EXPIRE - expire news database articles by number of days since rx'd
-
-
- Copyright (C) 1991 John McCombs, PO Box 2708, Christchurch, NEW ZEALAND
- john@ahuriri.gen.nz
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 1, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the file COPYING, which contains a copy of the GNU General
- Public License.
-
- USAGE: expires [<days>]
-
- */
-
- /*---------------------------- Source Control ------------------------------*/
-
- /*
- * $Id: EXPIRE.C,v 1.2 1994/02/05 18:46:56 gbj Exp user $
- */
-
- /****************************************************************************
- * 02 Jul 92 1.2 GT Change history file name. *
- * 01 Sep 92 1.3 MSM Selective expire *
- * 21 Nov 92 1.4 MSM Colour Support *
- * 16 Dec 92 1.5 MSM Expiry of snews history file *
- * 20 Dec 92 1.6 MSM Archiving of Newsgroups *
- * 31 May 93 1.7 MSM Achive file problem fixed *
- * Token in archive file corrected *
- * Snews 2.0 *
- * 19 Jun 93 1.8 MSM Memory allocation / free routines corrected *
- * 26 Sep 93 1.9 MSM Last item bug in read_expire fixed *
- * 18 Oct 93 1.10 MSM Minor long int corrections *
- * Return codes added *
- * 5 Dec 93 1.11 MSM Subject limited to 128 characters *
- * 2 Apr 94 1.12 MSM Check added for uot of time sequence articles *
- * (with thanks to ubik.demon.co.uk) *
- * If an article is found to be out of sequence *
- * its time stamp is corrected *
- ****************************************************************************/
-
- #include "defs.h"
- #include "expire.h"
- #include "locking.h"
- #include "screen.h"
-
- #include <io.h>
- #include <fcntl.h>
- #include <ctype.h>
-
- #ifdef ATARI
- # include "st.h"
- #endif
-
- #ifndef __TURBOC__
- #ifndef ATARI
- #define BLACK 0
- #define LIGHTGRAY 7
- #endif
- #endif
-
- extern int scr_x, scr_y;
-
- void scroll_up(int);
-
- int selective;
-
- INFO my_stuff;
-
- EXP_DATA *exp_entry, *exp_first;
-
- /*------------------------------- main --------------------------------*/
- int main(int argc, char *argv[])
- {
-
- /*
- * This routine expires the news database thus:
- * - copy the index and text files into new ones, omitting the old ones
- * - update the article counters
- * - delete the old articles and rename the new files
- * - print the totals
- *
- * TODO: It's too big a hunk break it up
- */
-
- ACTIVE *gp, *head;
- char *fn, buf[256], buf2[256], subject[256], arc_file[65];
- struct stat st;
- time_t current;
- long secs, i, offset;
- int days;
- int ch;
- int no_space;
- int flag_s;
- int ret_code;
- long art_time;
- long prev_art_time;
- long where;
- long exp_default;
-
- FILE *index;
- FILE *old_index;
- FILE *text;
- FILE *old_text;
- FILE *arch;
-
- int articles;
- int articles_deleted;
- int articles_archived;
- int gp_art;
- int gp_art_deleted;
- int gp_art_archived;
- int gp_flag;
-
- long total_bytes;
- long total_bytes_deleted;
- long total_bytes_archived;
- long gp_bytes;
- long gp_bytes_deleted;
- long gp_bytes_archived;
-
-
- articles = 0;
- articles_deleted = 0;
- articles_archived = 0;
-
- total_bytes = 0l;
- total_bytes_deleted = 0l;
- total_bytes_archived = 0l;
- arc_file[0] = '\0';
-
- if (!load_stuff()) {
- fprintf(stderr, "expire: couldn't read rc info\n");
- }
-
- v_init(my_stuff.directvideo); /* initialise bios video package */
-
- fprintf(stderr, "Demon Internet Services Simple News v%d.%2d [build %d]\n",
- rmj, rmm, rup);
- fprintf(stderr, "Expire Old News\n\n");
-
- if (argc <= 2) {
-
- head = load_active_file();
-
- time(¤t);
-
- selective = TRUE;
-
- if (argc == 2) {
- if (isdigit(argv[1][0]) && (atoi(argv[1]) >= 0)) {
- days = atoi(argv[1]);
- secs = (long) days * 86400l;
- selective = FALSE;
- exp_default = secs;
- gotoxy(1, 3);
- printf("expire: Retain %d days in all newsgroups ? ", days);
- ch = getch();
- putch(ch);
- putch('\n');
- ch = tolower(ch);
- if (ch != 'y')
- exit(1);
- }
- else {
- fprintf(stderr, "expire: Invalid day count specified.\n");
- exit(1);
- }
- }
- else {
-
- if (load_expire() == FALSE) {
- fprintf(stderr, "expire: Error loading expiry data.\n");
- exit(1);
- }
-
- if (read_expire("[DEFAULT]", &exp_default, arc_file) == FALSE) {
- fprintf(stderr, "expire: Unable to find default expire item [default].\n");
- exit(1);
- }
- }
-
- gp = head;
-
- clrscr();
-
- textbackground(textb);
- textcolor(textf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- clreol();
- printf("NEWSGROUP : EXPIRE ARTICLES REMOVED \r\n");
- clreol();
- textbackground(textb);
- textcolor(textf);
- printf("\r\n");
- clreol();
-
- while (gp != NULL) {
-
- no_space = FALSE;
-
- gp_art = 0;
- gp_art_deleted = 0;
- gp_art_archived = 0;
- gp_bytes = 0l;
- gp_bytes_deleted = 0l;
- gp_bytes_archived = 0l;
- gp_flag = FALSE;
-
- if ((gp->hi_num - gp->lo_num) > 0l) {
-
- /*
- * Open all the files. First the old ones, then the new
- */
-
- fn = make_news_group_name(gp->group);
- prev_art_time = 0l;
-
- if (selective) {
- if (read_expire(gp->group, &secs, arc_file) == FALSE)
- secs = exp_default;
- if (secs < 0l)
- secs = -1l;
- }
- stat(fn, &st);
- if (*arc_file == '\0')
- gp_bytes_deleted = st.st_size;
- else
- gp_bytes_archived = st.st_size;
-
- if ((old_text = fopen(fn, "rb")) == NULL)
- crash("can't open old text", fn);
- #ifdef ATARI
- setvbuf(old_text, NULL, _IOFBF, 32767);
- #else
- setvbuf(old_text, NULL, _IOFBF, 16384);
- #endif
- sprintf(buf, "%s.IDX", fn);
- if ((old_index = fopen(buf, "rb")) == NULL)
- crash("can't open old index", buf);
-
- sprintf(buf, "%s.NEW", fn);
- if ((text = fopen(buf, "wb")) == NULL)
- crash("can't create new text", buf);
- #ifdef ATARI
- setvbuf(text, NULL, _IOFBF, 32767);
- #else
- setvbuf(text, NULL, _IOFBF, 16384);
- #endif
- sprintf(buf, "%s.NDX", fn);
- if ((index = fopen(buf, "wb")) == NULL)
- crash("can't create new index", buf);
-
- if (selective && (*arc_file != '\0')) {
- if ((arch = fopen(arc_file, "at")) == NULL)
- crash("can't open archive", arc_file);
- }
- /* numbers go chronologically */
- for (i = (gp->lo_num) + 1l; i <= gp->hi_num; i++) {
-
- fgets(buf, 255, old_index);
- if (i != atol(buf + 9)) {
- fprintf(stderr, "\nexpire: In %s article %ld found when %ld"
- " expected\n", gp->group, atol(buf + 9), i);
- exit(1);
- }
-
- /* get the time the article was processed */
- art_time = atol(buf + 18);
- if ((gp_flag == FALSE) &&
- (((long) current - art_time) > secs) && (secs >= 0l)) {
-
- /*
- * Older than req'd - just count the totals
- */
-
- if (*arc_file == '\0')
- gp_art_deleted++;
- else
- gp_art_archived++;
-
- gp->lo_num++;
- update_active_entry(gp);
-
- if (*arc_file != '\0') {
- where = ftell(text);
- offset = atol(buf);
- fseek(old_text, offset, SEEK_SET);
- if (fputs("\n#! rnews\n", arch) == EOF) {
- no_space = TRUE;
- break;
- }
- while (fgets(buf, 255, old_text)) {
- if (strnicmp(buf, "@@@@END", 7) != 0) {
- if (fputs(buf, arch) == EOF) {
- no_space = TRUE;
- break;
- }
- }
- else
- break;
- }
- }
- }
- else {
-
- /*
- * Younger than limit, so keep the article
- */
- where = ftell(text);
- gp_flag = TRUE;
-
- /* copy to new file */
- offset = atol(buf);
- flag_s = 0;
- fseek(old_text, offset, SEEK_SET);
- while (fgets(buf, 255, old_text)) {
-
- if ((strnicmp(buf, "Subject:", 8) == 0) && (flag_s == 0)) {
- flag_s = 1;
- if (strlen(buf) > 136) {
- buf[136] = '\n';
- buf[137] = '\0';
- }
- strcpy(subject, buf + 8);
- }
- if (fputs(buf, text) == EOF) {
- no_space = TRUE;
- break;
- }
- if (strnicmp(buf, "@@@@END", 7) == 0)
- break;
- }
-
- /* save the header info */
- if (prev_art_time != 0) {
- if (art_time < prev_art_time)
- art_time = prev_art_time;
- }
- fprintf(index, "%08ld %08ld %09ld %s", where, i,
- art_time, subject);
- prev_art_time = art_time;
- }
-
- if (no_space)
- break;
- }
-
- /*
- * Close and rename the files
- */
-
- fclose(old_text);
- fclose(old_index);
- fclose(text);
- fclose(index);
- if (*arc_file != '\0')
- fclose(arch);
-
- fn = make_news_group_name(gp->group);
-
- /* out of disk on expire, delete the temp files */
-
- if (no_space) {
- printf("expire: Disk error expiring %s\n", gp->group);
- sprintf(buf2, "%s.NEW", fn);
- unlink(buf2);
- sprintf(buf2, "%s.NDX", fn);
- unlink(buf2);
- }
- else {
- unlink(fn);
- sprintf(buf2, "%s.NEW", fn);
- stat(buf2, &st);
- gp_bytes = st.st_size;
- rename(buf2, fn);
-
- sprintf(buf, "%s.IDX", fn);
- unlink(buf);
- sprintf(buf2, "%s.NDX", fn);
- rename(buf2, buf);
- }
-
- /* print all groups with articles */
-
- gp_art = (int) (gp->hi_num - gp->lo_num);
- if (*arc_file == '\0')
- gp_bytes_deleted -= gp_bytes;
- else
- gp_bytes_archived -= gp_bytes;
-
- articles += gp_art;
- total_bytes += gp_bytes;
- if (*arc_file == '\0') {
- articles_deleted += gp_art_deleted;
- total_bytes_deleted += gp_bytes_deleted;
- }
- else {
- articles_archived += gp_art_archived;
- total_bytes_archived += gp_bytes_archived;
- }
- if ((gp_art > 0) || (gp_art_deleted > 0) || (gp_art_archived > 0)) {
-
- if (gp_art_deleted > 0)
- printf("%-35s : %4d %4d %5ldKb %4d %5ldKb\n",
- gp->group,
- (int) (secs / 86400l),
- gp_art, (gp_bytes + 500l) / 1000l,
- gp_art_deleted, (gp_bytes_deleted + 500l) / 1000l);
-
- if (gp_art_archived > 0)
- printf("%-35s : %4d %4d %5ldKb %4d %5ldKb A\n",
- gp->group,
- (int) (secs / 86400l),
- gp_art, (gp_bytes + 500l) / 1000l,
- gp_art_archived, (gp_bytes_archived + 500l) / 1000l);
-
- if ((gp_art_deleted < 1) && (gp_art_archived < 1)) {
- if ((secs > 315300000l) || (secs < 0l))
- ch = -1;
- else
- ch = (int) (secs / 86400l);
- printf("%-35s : %4d %4d %5ldKb\n",
- gp->group,
- ch,
- gp_art, (gp_bytes + 500l) / 1000l);
- }
- if (scr_y == scr_rows)
- scroll_up(3);
- }
- }
- gp = gp->next;
- }
-
- close_active_file();
-
- scroll_up(3);
- scroll_up(3);
- scroll_up(3);
-
- gotoxy(1, scr_rows - 1);
-
- printf("Expiring snews history file \"history.snw\" ...\n");
-
- secs = exp_default;
- expire_history(current, secs);
-
- if (selective) {
-
- scroll_up(3);
- scroll_up(3);
- scroll_up(3);
-
- gotoxy(1, scr_rows - 1);
-
- printf("Processing nntp history file \"history\" ...\n");
-
- scroll_up(3);
- scroll_up(3);
- gotoxy(1, scr_rows - 1);
-
- if (read_expire("[TAIL]", &exp_default, arc_file) == TRUE)
- nntp_tail(exp_default);
- else {
- if (read_expire("[COPY]", &exp_default, arc_file) == TRUE)
- nntp_copy();
- }
- }
- exp_free();
-
- #ifndef ATARI
- textbackground(BLACK);
- textcolor(LIGHTGRAY);
-
- clrscr();
-
- gotoxy(1, 1);
- #endif
-
- printf("\n\nexpire: Processing Summary...\n\n");
- printf("\t%7ld articles deleted \n"
- "\t%7ld articles archived \n"
- "\t%7ld Kb deleted \n"
- "\t%7ld Kb archived \n"
- "\t%7ld articles remaining \n"
- "\t%7ld Kb of text remaining \n",
- articles_deleted,
- articles_archived,
- (total_bytes_deleted + 500l) / 1000l,
- (total_bytes_archived + 500l) / 1000l,
- articles,
- (total_bytes + 500l) / 1000l);
-
- gotoxy(1, scr_rows - 5);
-
- ret_code = 0;
- }
- else {
- fprintf(stderr, "usage: expire [<days>]\n");
- ret_code = 1;
- }
- #ifdef ATARI
- printf("\033q");
- gotoxy(1, scr_rows);
- printf("\n\n");
- #endif
- return ret_code;
- }
-
-
- /*----------------------------------------------------------------------*/
- void crash(char *msg, char *fn)
- {
-
- /*
- * Abort if file open error
- */
-
- fprintf(stderr, "\nexpire: %s, %s\n", msg, fn);
- exit(1);
- }
-
-
- /*--------------------------- expire history entries --------------------*/
- void expire_history(long current, long secs)
- {
- FILE *hist_file, *new_hist_file;
- long age, test, life;
- char buf[512], buf2[512], buf3[512], arc_file[65], *newsgroup, *p;
- int flag;
- size_t bufsize;
-
- /* open the files */
- sprintf(buf, "%shistory.snw", my_stuff.news_dir);
- if ((hist_file = fopen(buf, "rb")) == NULL) {
- fprintf(stderr, "expire: cannot open file %s for input\n", buf);
- exit(1);
- }
-
- for (bufsize = (size_t) 32767U;
- setvbuf(hist_file, NULL, _IOFBF, bufsize) != 0 && bufsize > 512;
- bufsize /= 2);
-
- sprintf(buf, "%shistory.new", my_stuff.news_dir);
- if ((new_hist_file = fopen(buf, "wb")) == NULL) {
- fprintf(stderr, "expire: cannot open file %s for output\n", buf);
- exit(1);
- }
-
- if (!selective) {
- while (fgets(buf, 255, hist_file) != NULL) {
- sscanf(buf, "%*s %ld", &age);
- if ((current - age) < secs) {
- fputs(buf, new_hist_file);
- }
- }
- }
- else {
- while (fgets(buf, 255, hist_file) != NULL) {
- test = secs;
- sscanf(buf, "%*s %ld", &age);
- strcpy(buf2, buf);
- p = strtok(buf2, " \n\r");
- strcpy(buf3, p); /* Article ID */
- p = strtok(NULL, " \n\r");
- strcat(buf3, " ");
- strcat(buf3, p); /* Posting Time */
- flag = FALSE;
- while ((p = strtok(NULL, " \n\r")) != NULL) {
- if ((*p == '\n') || (*p == '\r'))
- break;
- newsgroup = p;
- p = strtok(NULL, " \n\r");
- if (read_expire("[LIFE]", &life, arc_file) == FALSE) {
- life = -1;
- }
- if (read_expire(newsgroup, &test, arc_file) == FALSE) {
- test = secs;
- }
- else {
- if (test < 0l)
- test = -1l;
- }
- if ((test == -1l) && (life != -1l)) {
- test = life;
- }
- if ((test > life) && (life != -1l))
- test = life;
- if ((test < 0l) || ((current - age) < test)) {
- strcat(buf3, " ");
- strcat(buf3, newsgroup);
- strcat(buf3, " ");
- strcat(buf3, p);
- flag = TRUE;
- }
- }
-
- if (flag == TRUE) {
- strcat(buf3, " \n");
- fputs(buf3, new_hist_file);
- }
- }
- }
-
- fclose(hist_file);
- fclose(new_hist_file);
-
- sprintf(buf, "%shistory.bak", my_stuff.news_dir);
- unlink(buf);
- sprintf(buf2, "%shistory.snw", my_stuff.news_dir);
- rename(buf2, buf);
- sprintf(buf, "%shistory.new", my_stuff.news_dir);
- rename(buf, buf2);
- sprintf(buf, "%shistory.bak", my_stuff.news_dir);
- unlink(buf);
-
- }
-
- /*---------------------- Load the expiry data to memory ------------------*/
-
- int load_expire()
- {
-
- char buf[80], buf2[80], *p;
- FILE *data;
-
- sprintf(buf, "%sexpire.dat", my_stuff.news_dir);
- if ((data = fopen(buf, "rt")) == NULL) {
- fprintf(stderr, "expire: Data file %sexpire.dat not found.\n",
- my_stuff.news_dir);
- exit(1);
- }
-
- while (fgets(buf, 80, data) != NULL) {
- if (buf[0] == '\x1a')
- break;
- if ((buf[0] == '#') || (buf[0] == '\n'))
- continue;
- strcpy(buf2, buf);
- if ((p = strtok(buf2, " ,\t\n\r")) == NULL) {
- fclose(data);
- return FALSE;
- }
-
- if (exp_first == NULL) {
- exp_first = (EXP_DATA *) malloc(sizeof(EXP_DATA));
- if (exp_first == NULL) {
- fprintf(stderr, "expire: Out of memory.\n");
- exit(1);
- }
- exp_first->next = NULL;
- exp_entry = exp_first;
- }
- else {
- exp_entry->next = (EXP_DATA *) malloc(sizeof(EXP_DATA));
- if (exp_entry->next == NULL) {
- fprintf(stderr, "expire: Out of memory.\n");
- exit(1);
- }
- exp_entry = exp_entry->next;
- exp_entry->next = NULL;
- }
-
- exp_entry->flag = FALSE;
- strcpy(exp_entry->group, buf2);
- if (exp_entry->group[strlen(exp_entry->group) - 1] == '*') {
- exp_entry->group[strlen(exp_entry->group) - 1] = '\0';
- exp_entry->flag = TRUE;
- }
-
- if ((p = strtok(NULL, " ,\t\r\n")) == NULL) {
- fclose(data);
- return FALSE;
- }
-
- exp_entry->days = atoi(p);
- if ((p = strtok(NULL, " ,\t\r\n")) != NULL) {
- strcpy(exp_entry->archive, p);
- }
- else {
- strcpy(exp_entry->archive, "\0");
- }
- }
- fclose(data);
- return TRUE;
- }
-
- /*-------------------------- Search expiry data struct --------------------*/
-
- int read_expire(char *target, long *len, char *arc)
- {
-
- char group[80];
- int days, match, test, flag;
-
- match = 0;
-
- exp_entry = exp_first;
-
- arc[0] = '\0';
-
- while (exp_entry != NULL) {
- flag = exp_entry->flag;
-
- strcpy(group, exp_entry->group);
-
- days = exp_entry->days;
-
- test = strlen(group);
-
- if ((test > match) && (flag)) {
- if (strnicmp(target, group, test) == 0) {
- *len = (long) days *86400l;
-
- strcpy(arc, exp_entry->archive);
- match = test;
- }
- }
- else {
- if (stricmp(target, group) == 0) {
- *len = (long) days *86400l;
-
- strcpy(arc, exp_entry->archive);
- match = test;
- }
- }
- exp_entry = exp_entry->next;
- }
-
- if (match != 0) {
- return TRUE;
- }
-
- return FALSE;
- }
-
- /*------------------------ Release Expire Data Memory ---------------------*/
-
- void exp_free()
- {
-
- EXP_DATA *exp_next;
-
- exp_entry = exp_first;
-
- while (exp_entry != NULL) {
- exp_next = exp_entry->next;
- free(exp_entry);
- exp_entry = exp_next;
- }
-
- }
-
- /*-------------------- Deal with the NNTP History File --------------------*/
-
- void nntp_tail(long size)
- {
-
- long start, lines, count;
- char buf[256], nntpfile[80], backfile[80], newfile[80];
- FILE *hf, *nf;
- size_t bufsize;
-
- lines = size / 86400l;
-
- printf("Removing all except last %ld lines from NNTP history.\n", lines);
- sprintf(nntpfile, "%shistory", my_stuff.nntp_dir);
- sprintf(backfile, "%shistory.bak", my_stuff.nntp_dir);
- sprintf(newfile, "%shistory.new", my_stuff.nntp_dir);
-
- if ((hf = fopen(nntpfile, "rt")) == NULL) {
- fprintf(stderr, "expire: unable to open nntp history file.\n");
- exit(1);
- }
-
- for (bufsize = (size_t) 32767U;
- setvbuf(hf, NULL, _IOFBF, bufsize) != 0 && bufsize > 512;
- bufsize /= 2);
-
- count = 0;
- while (fgets(buf, 256, hf) != NULL)
- count++;
- rewind(hf);
- if (count < lines) { /* nothing to do */
- fclose(hf);
- return;
- }
- start = count - lines;
-
- if ((nf = fopen(newfile, "wt")) == NULL) {
- fprintf(stderr, "expire: Unable to create new nntp history.\n");
- exit(1);
- }
-
- count = 0;
- while (fgets(buf, 255, hf) != NULL)
- if (++count > start)
- fputs(buf, nf);
-
- fclose(hf);
- fclose(nf);
-
- unlink(backfile);
- rename(nntpfile, backfile);
- rename(newfile, nntpfile);
-
- }
-
- /*------------------------------ Copy Snews to nntp ------------------------*/
-
- void nntp_copy()
- {
-
- char buf[256], snewsfile[80], nntpfile[80], newfile[80], backfile[80];
- char *p;
- FILE *sf, *nf;
- size_t bufsize;
-
- printf("Copying Snews History to NNTP history.\n");
- sprintf(snewsfile, "%shistory.snw", my_stuff.news_dir);
- sprintf(nntpfile, "%shistory", my_stuff.nntp_dir);
- sprintf(newfile, "%shistory.new", my_stuff.nntp_dir);
- sprintf(backfile, "%shistory.bak", my_stuff.nntp_dir);
-
- if ((sf = fopen(snewsfile, "rt")) == NULL) {
- fprintf(stderr, "expire: Unable to open snews history.\n");
- exit(1);
- }
-
- for (bufsize = (size_t) 32767U;
- setvbuf(sf, NULL, _IOFBF, bufsize) != 0 && bufsize > 512;
- bufsize /= 2);
-
- if ((nf = fopen(newfile, "wt")) == NULL) {
- fprintf(stderr, "expire: Unable to create new nntp history.\n");
- exit(1);
- }
-
- while (fgets(buf, 255, sf) != NULL) {
- p = strtok(buf, " \t\n\r");
- fputs(p, nf);
- fputs("\n", nf);
- }
-
- fclose(nf);
- fclose(sf);
- unlink(backfile);
- rename(nntpfile, backfile);
- rename(newfile, nntpfile);
- }
-